package _17_剑指Offer;

import _17_剑指Offer.datastrcute.TreeNode;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class _68_剑指OfferII二叉树的最近公共祖先 {

    // 存放当前节点，对应的祖先节点的映射关系
    private final Map<TreeNode, TreeNode> parentMap = new HashMap<>();

    private final Set<TreeNode> visited = new HashSet<>();

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        dfs(root);
        // 查找p的所有祖先节点
        while (p != null) {
            visited.add(p);
            p = parentMap.get(p);
        }
        // 查找q
        while (q != null) {
            if (visited.contains(q)) {
                return q;
            }
            q = parentMap.get(q);
        }
        return null;
    }

    private void dfs(TreeNode root) {
        if (root.left != null) {
            parentMap.put(root.left, root);
            dfs(root.left);
        }
        if (root.right != null) {
            parentMap.put(root.right, root);
            dfs(root.right);
        }
    }

    // 递归查找
    public TreeNode lowestCommonAncestor1(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) return root;

        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);

        // 如果左右节点都存在，那么就是当前root节点
        if (left != null && right != null) return root;

        // 存在的那个节点即为祖先节点
        return left == null ? right : left;
    }

}
